#pragma once 
#include<iostream>
#include<string>
#include<vector>
#include<unordered_map>

static const std::string sep = "\r\n";
static const std::string header_sep = ": ";
static const std::string wwwroot = "wwwroot";
static const std::string homepage = "index.html";
static const std::string httpversion = "HTTP/1.0";
static const std::string space = " ";
static const std::string filesuffixsep = ".";
static const std::string args_sep = "?";


class HttpRequest
{
    private:
        //原始协议内容
        std::string _req_line;
        std::vector<std::string> _req_headler;
        std::string _blank_line;
        std::string _req_text;
        //期望解析结果
        std::string _method;
        std::string _url;
        std::string _args;
        std::string _path;
        std::string _suffix;
        std::string _version;   

        std::unordered_map<std::string,std::string> _headers;
    private:
        std::string GetOneline(std::string& reqstr)
        {
            if(reqstr.empty())
            {
                return requstr;
            }
            auto pos = reqstr.find(sep);
            if(pos == std::string::npos)
            {
                return std::string();
            }
            std::string line = reqstr.substr(0, pos);
            reqstr.erase(0, pos + sep.size());
            return line.empty() ? sep : line;
        }
        bool ParseHeaderHelper(const std::string &line, std::string* k,std::string*v)
        {
            auto pos = line.find(header_sep);
            if(pos == std::string::npos)
                return false;
            
        }

    public:
        HttpRequest()
        :_blank_line(sep)
        ,_path(wwwroot)
        {}
        void Serialize()
        {

        }
        void Derialize(std::string& reqstr)
        {
            _req_line = GetOneline(reqstr);
            while(true)
            {
                std::string line = GetOneline(reqstr);
                if(line.empty())
                {
                    break;
                }
                else if(line == sep)
                {
                    _req_text = reqstr;
                    break;
                }
                else 
                {
                    _req_headler.emplace_back(line);
                }
            }
            ParseReqline();
            ParseHander();
        }
        void Print()
        {
            
        }
        bool ParseReqline()
        {
            if(_req_line.empty())
                return false;
            std::stringstream ss(_req_line);
            ss>> _method >> _url >> _version;

            if(strcasecmp("get",_method.c_str()) == 0)
            {
                //格式
                //index.html?use=zhangsan&passwd=123456
                auto pos = _url.find(args_sep);
                if(pos != std::string::npos)
                {
                    LOG(INFO,"change begin, url: %s \n",_url.c_str());
                    _args = url.substr(pos + args_sep.size());
                    _url.resize(pos);
                    LOG(INFO, "change done, url: %s, _args: %s\n", _url.c_str(), _args.c_str());
                }
            }
            _path += _url;
            LOG(DEBUG, "url: %s\n",_url.c_str());
        }
        bool ParseHander()
        {

        }
};
class HttpResponse
{
    private:
        //构建应答的必要手段
        std::string _version;
        int _code;
        std::string _desc;
        std::unordered_map<std::string,std::string> _headlers;
        //应答结构化字段
        std::string _status_line;
        std::vector<std::string> _resp_headler;
        std::string _blank_line;
        std::string _resp_text;

    public:
        HttpResponse()
        :_version(httpversion)
        ,_blank_line(sep)
        {}
        ~HttpRequest()
        {}
        void AddStatusLine(int code,const std::string& desc)
        {

        }
        void AddHeader(const std::string& k,const std::string& v)
        {

        }
        void AddText(const std::string&text)
        {

        }
        std::string Serialize()
        {

        }
};
class Factory{
    public:
        static std::shared_ptr<HttpRequest> BuildHrppRequest()
        {
            
        }
        static std::shared_ptr<HttpRequest> BuildHrppRequest()
        {

        }
};

class HttpServer
{
    private:
        std::unordered_map<std::string,std::string> _mime_type;
        std::unordered_map<int, std::string> _code_to_desc;
        std::unordered_map<std::string, func_t> _func;
    public:
        HttpServer()
        {

        }
        void AddHandler(const std::string functionname,func_t f)
        {

        }
        std::string ReadFileContent(const string& path, int* size)
        {

        }
        std::string HandlerHttpRequust(std::string req)
        {
#ifdef TEST

#else

#endif
        }

        ~HttpServer()
        {}
};

